package query

import (
	"github.com/romberli/das/internal/app/metadata"
	"github.com/romberli/das/internal/dependency/query"
	"github.com/romberli/go-util/common"
	"github.com/romberli/go-util/constant"
)

const QueriesStruct = "Queries"

var _ query.Service = (*Service)(nil)

type Service struct {
	config  query.Config
	dasRepo query.DASRepo
	Queries []query.Query `json:"queries"`
}

// NewService returns a new query.Service
func NewService(config query.Config, dasRepo query.DASRepo) query.Service {
	return newService(config, dasRepo)
}

// NewServiceWithDefault returns a new query.Service with default repository
func NewServiceWithDefault(config query.Config) query.Service {
	return newService(config, NewDASRepoWithGlobal())
}

// newService returns a new *Service
func newService(config query.Config, dasRepo query.DASRepo) *Service {
	return &Service{
		config:  config,
		dasRepo: dasRepo,
	}
}

// GetConfig returns the config of query
func (s *Service) GetConfig() query.Config {
	return s.config
}

// GetQueries returns the queries
func (s *Service) GetQueries() []query.Query {
	return s.Queries
}

// GetByMySQLClusterID gets the queries by the mysql cluster identity
func (s *Service) GetByMySQLClusterID(mysqlClusterID int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByMySQLClusterIDWithHTTP(mysqlClusterID)

	return err
}

// GetByMySQLServerID gets the queries by the mysql server identity
func (s *Service) GetByMySQLServerID(mysqlServerID int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByMySQLServerIDWithHTTP(mysqlServerID)

	return err
}

// GetByHostInfo gets the queries by the mysql server host ip and port number
func (s *Service) GetByHostInfo(hostIP string, portNum int) error {
	mysqlServerService := metadata.NewMySQLServerServiceWithDefault()
	err := mysqlServerService.GetByHostInfo(hostIP, portNum)
	if err != nil {
		return err
	}
	mysqlServerID := mysqlServerService.GetMySQLServers()[constant.ZeroInt].Identity()
	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByMySQLServerIDWithHTTP(mysqlServerID)

	return err
}

// GetByMySQLServerAndMonitorSystemInfo gets the queries by the mysql server and monitor system info
func (s *Service) GetByMySQLServerAndMonitorSystemInfo(
	mysqlServerHostIP string, mysqlServerPortNum int, mysqlServerServiceName string,
	monitorSystemSystemType int, monitorSystemHostIP string, monitorSystemPortNumSlow int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByMySQLServerAndMonitorSystemInfoWithHTTP(
		mysqlServerHostIP, mysqlServerPortNum, mysqlServerServiceName,
		monitorSystemSystemType, monitorSystemHostIP, monitorSystemPortNumSlow)

	return err
}

// GetByDBID gets the query slice by the db identity
func (s *Service) GetByDBID(dbID int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByDBID(dbID)

	return err
}

// GetByDBNameAndMySQLServerAndMonitorSystemInfo gets the queries by the db name and mysql server and monitor system info
func (s *Service) GetByDBNameAndMySQLServerAndMonitorSystemInfo(dbName string,
	mysqlServerHostIP string, mysqlServerPortNum int, mysqlServiceName string,
	monitorSystemSystemType int, monitorSystemHostIP string, monitorSystemPortNumSlow int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByDBNameAndMySQLServerAndMonitorSystemInfo(dbName,
		mysqlServerHostIP, mysqlServerPortNum, mysqlServiceName,
		monitorSystemSystemType, monitorSystemHostIP, monitorSystemPortNumSlow)

	return err
}

// GetByMySQLServerIDAndSQLID gets the query by the mysql server identity and the sql identity
func (s *Service) GetByMySQLServerIDAndSQLID(mysqlServerID int, sqlID string) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetByMySQLServerIDAndSQLID(mysqlServerID, sqlID)

	return err
}

// GetBySQLIDAndMySQLServerAndMonitorSystemInfo gets the queries by the sql id and mysql server and monitor system info
func (s *Service) GetBySQLIDAndMySQLServerAndMonitorSystemInfo(sqlID string,
	mysqlServerHostIP string, mysqlServerPortNum int, mysqlServiceName string,
	monitorSystemSystemType int, monitorSystemHostIP string, monitorSystemPortNumSlow int) error {
	var err error

	querier := NewQuerierWithGlobal(s.GetConfig())
	s.Queries, err = querier.GetBySQLIDAndMySQLServerAndMonitorSystemInfo(sqlID,
		mysqlServerHostIP, mysqlServerPortNum, mysqlServiceName,
		monitorSystemSystemType, monitorSystemHostIP, monitorSystemPortNumSlow)

	return err
}

// Marshal marshals Service.Queries to json bytes
func (s *Service) Marshal() ([]byte, error) {
	return common.MarshalStructWithFields(s, QueriesStruct)
}
